#!/bin/bash
#
# Copyright 2015-2017 Adrian DC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# === ADB Logcat Reader ===
function adbl()
{
  # Variables
  local adb_log=${2:-adb.log};
  local buffer;
  local logcat;

  # Buffer selection
  case "${1}" in
    all|'') buffer='all';;
    crash)  buffer='crash';;
    events) buffer='events';;
    main)   buffer='main';;
    radio)  buffer='radio';;
    system) buffer='system';;
    help|*)
      echo '';
      echo ' Usage: adbl [all/crash/events/main/radio/system] [file_output] [bool_clean] (adb Logcat helper)';
      echo '';
      return;;
  esac;

  # Verify adb is ready
  adbready;

  # Check buffer available
  logcat=$(adb shell "if [ -d /dev/log ] && [ ! -e /dev/log/${buffer} ]; then echo false; fi;");
  if [ ! -z "${logcat}" ]; then

    # Recursive call when without parameter
    if [ -z "${1}" ]; then
      adbl 'main' "${2}" "${3}";
      return;
    fi;

    # Abort on missing buffer
    echo '';
    echo " adbl: Buffer '${buffer}' is not available. Use 'adbl help' to list possible buffers";
    echo '';
    return;
  fi;

  # Logcat command
  logcat="adb logcat -b ${buffer}";

  # Logcat read
  while true; do
    cls;
    echo -n '' > "${adb_log}";

    # Logs clean output
    if [ ! -z "${3}" ]; then
      ${logcat} -v threadtime '*:V' \
        | cut -c 32- \
        | sed -E "s/[0-9]{8}/00000000/g" \
        | sed -E "s/\[[0-9]*\]/[...]/g" \
        | sed -E "s/@[0-9a-f]{6,8}/@......./g" \
        | sed -E "s/\{[0-9a-f]{6,8}\}/{.......}/g" \
        | tee -a "${adb_log}";

    # Logs clean output
    else
      ${logcat} -v threadtime '*:V' \
        | tee -a "${adb_log}";
    fi;

    # End of logs
    echo '';
    echo -n 'Press Enter to continue... ';
    read -r;
  done;
}

# === ADB Logcat Relevant Reader ===
function adblr()
{
  # Usage: adblr (Logcat output relevant reader)

  # Verify adb is ready
  adbready;

  # Logcat output relevant reader
  adbl | grep -av 'Diag_Lib:';
}

# === ADB Logcat Public Cleaner ===
function adblpcln()
{
  # Usage: adblpcln [file_adb.log] (Logcat output public cleaner)

  # Clean input file
  filename=${1:-adb.log};
  mv -f "${filename}" "${filename}.orig";
  grep -v chatty "${filename}.orig" \
      | cut -c "${2:-32}-" \
      | sed -E "s/[0-9]{8}/00000000/g" \
      | sed -E "s/\[[0-9]*\]/[...]/g" \
      | sed -E "s/@[0-9a-f]{6,8}/@......./g" \
      | sed -E "s/\{[0-9a-f]{6,8}\}/{.......}/g" \
      | tee "${filename}";
}

# === ADB Logcat Cleaner ===
function adblcln()
{
  # Usage: adblcln [file_adb.log] (Logcat output cleaner)

  # Clean input file
  mv -f "${1}" "${1}.orig";
  cut -c 32- "${1}.orig" | tee "${1}";
}

# === ADB Dmesg Cleaner ===
function adbdcln()
{
  # Usage: adbdcln [file_adb.log] (dmesg output cleaner)

  # Clean input file
  mv -f "${1}" "${1}.orig";
  cut -d']' -f 2- "${1}.orig" | tee "${1}";
}

# === ADB Kernel Logs Cleaner ===
function adbkcln()
{
  # Usage: adbkcln [file_kmsg] (Kernel logs output cleaner)

  # Clean input file
  mv -f "${1}" "${1}.orig";
  cut -c 15- "${1}.orig" | tee "${1}";
}

# === ADB Strace Cleaner ===
function adbstcln()
{
  # Usage: adbstcln [file_adb.log] (strace output cleaner)

  # Clean input file
  filename=${1:-adb.log};
  mv -f "${filename}.orig" "${filename}";
  grep -v chatty "${filename}.orig" \
      | sed -E "s/[0-9]{8}/00000000/g" \
      | sed -E "s/\[[0-9]*\]/[...]/g" \
      | sed -E "s/@[0-9a-f]{6,8}/@......./g" \
      | sed -E "s/0x[0-9a-f]{6,8}/0x......./g" \
      | sed -E "s/\{[0-9a-f]{6,8}\}/{.......}/g" \
      | tee "${filename}";
}

# === ADB Loggers Helpers ===
alias adbld='cls; echo -n '' > adb.data; adbsu cat /data/logcat.txt | tee -a adb.data';
alias adblb='while true; do cls; echo -n "" > adb.log; adb logcat -v audit2allow *:V | tee -a adb.log;
             echo ""; echo -n "Press Enter to continue... "; read -r; done';
alias adblc='adb logcat -c; adbl';
alias adbk='echo -n '' > kmsg; adbsu cat /proc/kmsg | tee -a kmsg';
alias adbdm='echo -n '' > dmesg; adbsu dmesg | tee -a dmesg';
alias adbkd='echo -n '' > kmsg; adbsu cat /proc/kmsg | tee -a kmsg';
alias adbkl='cls; echo -n '' > last_kmsg; adbsu cat /proc/last_kmsg | tee -a last_kmsg';
alias adbpl='cls; echo -n '' > last_kmsg; adbsu cat /sys/fs/pstore/console-ramoops | tee -a last_kmsg';
alias adbrl='cls; echo -n '' > recovery_log; adbsu cat /tmp/recovery.log | tee -a recovery_log';
alias adbdumpsensors='adbsu dumpsys sensorservice';
alias adblf='adb logcat -v audit2allow';
alias adblh='adb logcat -b events -b main -b radio | highlight';
alias adbtrampoline='adbsu "dmesg | grep -i trampoline"';

# === ADB Ramoops Compressed Logger ===
function adbple()
{
  # Usage: adbple (ADB Ramoops Compressed Logger)
  # Prepare last_kmsg
  cls;
  echo -n '' > last_kmsg;

  # Pull logs file
  adb pull /sys/fs/pstore/dmesg-ramoops-0.enc.z;

  # Decompress and display logs content
  sed -i '1d' ./dmesg-ramoops-0.enc.z;
  zlib-flate -uncompress  < ./dmesg-ramoops-0.enc.z;
}

# === ADB Init Bootchart ===
function adbbootchart()
{
  # Usage: adbbootchart (Bootchart debug helper)

  # Clean previous bootcharts
  rm -rf /tmp/android-bootchart/;
  rm -f ./bootchart.png;

  # Timeout configuration
  echo '';
  echo -n ' Timeout in seconds ? [Enter] ';
  read -r timeinput;
  if [ -z "${timeinput}" ]; then
    timeinput=120;
  fi;

  # Set bootchart timeout
  adb shell "echo ${timeinput} > /data/bootchart/start";

  # Reboot
  echo -n ' Reboot Android ? [Enter] ';
  read -r;
  adb reboot;

  # Listen for device
  echo ' Waiting for the device to boot...';
  adbwait;

  # Wait for timeout or break
  echo -n ' Export Logs now ? [Enter] ';
  read -r -t "${timeinput}";

  # End bootchart
  adb shell 'echo 1 > /data/bootchart/stop'
  adb shell 'rm /data/bootchart/start';

  # Export bootchart results
  sleep 1;
  "${ANDROID_DEV_DRIVE}/LineageOS/system/core/init/grab-bootchart.sh";
  echo '';
}
